﻿using System;
using System.Collections.Generic;
using System.Text;
using MySql.Data.MySqlClient;
using System.Data;
using System.IO;

namespace php_pa_generator
{
    class Program
    {
        static void Main(string[] args)
        {
            if(args.Length!=4)
            {
                Console.WriteLine("BAD PARAMETERS");
                Console.WriteLine();
                Console.WriteLine("Usage:");
                Console.WriteLine("Command line: [mono] php_pa_generator.exe server_url user pass db_name");
                Console.WriteLine();
                return;
            }

            string db_url = args[0];
            string user = args[1];
            string pass = args[2];
            string db_name = args[3];
            string file_name = "procedures.php";
            string main = "main";
            string procedure = "procedure";
            string proc_fetch = string.Format("select name,param_list from mysql.proc where db = '{0}' and type = 'PROCEDURE';",db_name);
            string connString = "Database={0};Data Source={1};User Id={2};Password={3}";
            string proceduresPlaceHolder = "[procedure_code]";

            MySqlConnection conn = new MySqlConnection(string.Format(connString,db_name,db_url,user,pass));
            try
            {
                conn.Open();
                Console.WriteLine("Connection success");
                MySqlCommand command = new MySqlCommand(proc_fetch, conn);
                MySqlDataAdapter adapter = new MySqlDataAdapter(command);
                DataSet data = new DataSet();
                adapter.Fill(data);
                Console.WriteLine("Procedures fetched:");
                Console.WriteLine(data.Tables[0].Rows.Count.ToString() + " found");

                string mainPHP = File.ReadAllText(main);
                string procedureTemplate = File.ReadAllText(procedure);
                Console.WriteLine("Main templates loaded");

                string proceduresPHP = getProceduresPHP(data,procedureTemplate);
                Console.WriteLine("Finished generating procedures code");

                mainPHP = string.Format(mainPHP, proceduresPHP, DateTime.Now.ToString());
                Console.WriteLine("PHP class finished");

                if (File.Exists(file_name))
                {
                    File.Delete(file_name);
                    Console.WriteLine("Old file deleted");
                }
                File.WriteAllText(file_name, mainPHP);
                Console.WriteLine(file_name + " file created");
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERRORS!!!");
                Console.Write(ex.ToString() + Environment.NewLine);
            }
            finally
            {
                conn.Close();
            }

            Console.WriteLine("Finished!!!");
            Console.WriteLine();
            Console.WriteLine("press a key to exit...");
            Console.ReadKey(true);
            return;
        }

        private static string getProceduresPHP(DataSet data, string procedureTemplate)
        {
            StringBuilder proceduresCode =new StringBuilder();

            foreach (DataRow row in data.Tables[0].Rows)
            {
                string procedureName = row[0].ToString();
                string procedureParamRaw = new System.Text.ASCIIEncoding().GetString((byte[])row[1]);
                string[] procedureParams = procedureParamRaw.Split(new string[]{","},StringSplitOptions.RemoveEmptyEntries);

                string paramsList = "";
                string paramsListPHP = "";

                if (procedureParams.Length > 0)
                {
                    proceduresCode.AppendLine("\t\t# Procedure list:");
                    for (int n = 0; n < procedureParams.Length; n++)
                    {
                        procedureParams[n] = "$" + procedureParams[n].Trim();
                        proceduresCode.AppendLine(string.Format("\t\t# {0}", procedureParams[n]));
                        procedureParams[n] = procedureParams[n].Split(new string[]{" "},StringSplitOptions.RemoveEmptyEntries)[0];
                    }
                    paramsList = string.Join(",", procedureParams);
                    paramsListPHP = "'\"." + string.Join(".\"','\".", procedureParams) + ".\"'";
                }

                proceduresCode.AppendFormat(procedureTemplate, procedureName,paramsList,paramsListPHP);

                proceduresCode.AppendLine();
            }

            return proceduresCode.ToString();
        }
    }
}
